Ví dụ về lập trình hàm Erlang

Tính giai thừa

-module(fact). % This is the file 'fact.erl', the module and the filename must match-export([fac/1]). % This exports the function 'fac' of arity 1 (1 parameter, no type, no name)fac(0) -> 1; % If 0, then return 1, otherwise (note the semicolon ; meaning 'else')fac(N) when N > 0, is_integer(N) -> N * fac(N-1).% Recursively determine, then return the result% (note the period . meaning 'endif' or 'function end')%% This function will crash if anything other than a nonnegative integer is given.%% It illustrates the "Let it crash" philosophy of Erlang.

Dãy Fibonacci

Thuật toán đệ quy đuôi tạo ra Dãy Fibonacci:

%% The module declaration must match the file name "series.erl" -module(series).%% The export statement contains a list of all those functions that form%% the module's public API.  In this case, this module exposes a single%% function called fib that takes 1 argument (I.E. has an arity of 1)%% The general syntax for -export is a list containing the name and%% arity of each public function-export([fib/1]).%% ---------------------------------------------------------------------%% Public API%% ---------------------------------------------------------------------%% Handle cases in which fib/1 receives specific values%% The order in which these function signatures are declared is a vital%% part of this module's functionality%% If fib/1 is passed precisely the integer 0, then return 0fib(0) -> 0;%% If fib/1 receives a negative number, then return the atom err_neg_val%% Normally, such defensive coding is discouraged due to Erlang's 'Let%% it Crash' philosophy; however, in this case we should explicitly%% prevent a situation that will crash Erlang's runtime enginefib(N) when N < 0 -> err_neg_val;%% If fib/1 is passed an integer less than 3, then return 1%% The preceding two function signatures handle all cases where N < 1,%% so this function signature handles cases where N = 1 or N = 2fib(N) when N < 3 -> 1;%% For all other values, call the private function fib_int/3 to perform%% the calculationfib(N) -> fib_int(N, 0, 1).%% ---------------------------------------------------------------------%% Private API%% ---------------------------------------------------------------------%% If fib_int/3 receives a 1 as its first argument, then we're done, so%% return the value in argument B.  Since we are not interested in the%% value of the second argument, we denote this using _ to indicate a%% "don't care" valuefib_int(1, _, B) -> B;%% For all other argument combinations, recursively call fib_int/3%% where each call does the following:%%  - decrement counter N%%  - Take the previous fibonacci value in argument B and pass it as%%    argument A%%  - Calculate the value of the current fibonacci number and pass it%%    as argument Bfib_int(N, A, B) -> fib_int(N-1, B, A+B).

Chương trình tương tự mà không có nhận xét giải thích:

-module(series).-export([fib/1]).fib(0) -> 0;fib(N) when N < 0 -> err_neg_val;fib(N) when N < 3 -> 1;fib(N) -> fib_int(N, 0, 1).fib_int(1, _, B) -> B;fib_int(N, A, B) -> fib_int(N-1, B, A+B).

Quicksort

Quicksort trong Erlang, sử dụng danh sách hiểu:[7]

%% qsort:qsort(List)%% Sort a list of items-module(qsort).     % This is the file 'qsort.erl'-export([qsort/1]). % A function 'qsort' with 1 parameter is exported (no type, no name)qsort([]) -> []; % If the list [] is empty, return an empty list (nothing to sort)qsort([Pivot|Rest]) ->    % Compose recursively a list with 'Front' for all elements that should be before 'Pivot'    % then 'Pivot' then 'Back' for all elements that should be after 'Pivot'    qsort([Front || Front <- Rest, Front < Pivot]) ++     [Pivot] ++    qsort([Back || Back <- Rest, Back >= Pivot]).

Ví dụ trên gọi đệ quy hàm qsort cho đến khi không còn gì để sắp xếp. Biểu thức [Front || Front <- Rest, Front < Pivot] là một danh sách hiểu, nghĩa là "Xây dựng một danh sách các phần tử Front sao cho Front là một phần tử của Rest, và Front nhỏ hơn Pivot." ++ là toán tử nối danh sách.

Hàm so sánh có thể được sử dụng cho các cấu trúc phức tạp hơn để dễ đọc.

Đoạn code sau sẽ sắp xếp danh sách theo độ dài:

% This is file 'listsort.erl' (the compiler is made this way)-module(listsort).% Export 'by_length' with 1 parameter (don't care about the type and name)-export([by_length/1]).by_length(Lists) -> % Use 'qsort/2' and provides an anonymous function as a parameter   qsort(Lists, fun(A,B) -> length(A) < length(B) end).qsort([], _)-> []; % If list is empty, return an empty list (ignore the second parameter)qsort([Pivot|Rest], Smaller) ->    % Partition list with 'Smaller' elements in front of 'Pivot' and not-'Smaller' elements    % after 'Pivot' and sort the sublists.    qsort([X || X <- Rest, Smaller(X,Pivot)], Smaller)    ++ [Pivot] ++    qsort([Y || Y <- Rest, not(Smaller(Y, Pivot))], Smaller).

Một Pivot lấy từ phần tử đầu tiên sẽ được cấp cho qsort() và phần còn lại của Lists được đặt tên là Rest. Lưu ý rằng biểu thức

[X || X <- Rest, Smaller(X,Pivot)]

không khác gì biểu thức dưới đây về hình thức

[Front || Front <- Rest, Front < Pivot]

ngoại trừ việc sử dụng hàm so sánh trong phần cuối. Biểu thức trên có thể diễn đạt là "Xây dựng danh sách các phần tử X sao cho X là một phần tử của Rest, và Smaller thì đúng", với Smaller được định nghĩa trước đó là:

fun(A,B) -> length(A) < length(B) end

Hàm ẩn danh được đặt tên là Smaller trong danh sách tham số của định nghĩa thứ hai của qsort để nó có thể được tham chiếu bởi tên đó trong hàm đó. Nó không được đặt tên trong định nghĩa đầu tiên của qsort.